package br.ufrrj.im.redes.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import br.ufrrj.im.redes.model.Message;
import br.ufrrj.im.redes.model.MessageClosingConnection;
import br.ufrrj.im.redes.model.ResultGameMessage;
import br.ufrrj.im.redes.model.StartGameMessage;
import br.ufrrj.im.redes.model.UpdateGameMessageForGamer;
import br.ufrrj.im.redes.util.Constants;

public class PersistentConnectionUser implements Runnable{
	
	private ServerSocket reciveConnectionSocket;
	private Socket connectionSocket;
	private ObjectInputStream streamFromServer;
	private ObjectOutputStream streamToServer;
	private Message msgFromServer;


	public PersistentConnectionUser() throws IOException {
		// TODO Auto-generated constructor stub		
		
		//cria socket para receber conexões do servidor
		reciveConnectionSocket = new ServerSocket(Constants.PORT_GAME_CONNECTION);
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
	
		//aguarda startGame do servidor
		do{
			
			try {
				
				connectionSocket = reciveConnectionSocket.accept();
				streamFromServer = new ObjectInputStream(connectionSocket.getInputStream());
				
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
			}		
			
		} while (!connectionSocket.isClosed());//(connectionSocket != null);
	}
	
	public int getStartGameMessage() throws ClassNotFoundException, IOException {
		//Recebe uma mensagem de início de jogo
		
		if(streamFromServer != null){
			msgFromServer = validateMessageFromServer(streamFromServer.readObject());	
			
			if (msgFromServer instanceof StartGameMessage)
				return ((StartGameMessage) msgFromServer).getRangePrime();
		}		
		
		return Constants.INVALID_RANGE_PRIME;
	}
	
	public Message getUpdateMessage() throws ClassNotFoundException, IOException {
		//aguarda mensagens de atualização do servidor
		if(streamFromServer != null){
			msgFromServer = validateMessageFromServer(streamFromServer.readObject());
			
			if ((msgFromServer instanceof ResultGameMessage) || (msgFromServer instanceof UpdateGameMessageForGamer))
				return msgFromServer;
		}
		
		return null;
	}
	
	public void closeConnection() throws IOException {
		if(connectionSocket != null)
			connectionSocket.close();
		if(reciveConnectionSocket != null)
			reciveConnectionSocket.close();
	}
	
	public void closeStreams() throws IOException{
		if(streamFromServer != null)
			streamFromServer.close();
		if(streamToServer != null)
			streamToServer.close();
	}
	
	
	public Message validateMessageFromServer(Object object){
		return (object instanceof Message) ? (Message) object : null;
	}
	
	
	public void sendMessageToServer(Message msg) throws IOException{
		streamToServer = new ObjectOutputStream(connectionSocket.getOutputStream());
		
		//escreve a mensagem na stream de saída do socket
		streamToServer.writeObject(msg);
	}
	
	
	//return 1 if is connected, otherwise return 0
	public boolean getStatusConnectionWithServer() throws ClassNotFoundException, IOException{
		if(streamFromServer != null){
			msgFromServer = validateMessageFromServer(streamFromServer.readObject());	
			
			if (msgFromServer instanceof MessageClosingConnection)
				return false;
		}		
		
		return true;

	}

}
